using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using ActivateYourGlutes.Data;
using ActivateYourGlutes.Infrastructure;
using ActivateYourGlutes.Infrastructure.Logging;
using ActivateYourGlutes.Services;

namespace ActivateYourGlutes.Controllers
{
    public partial class AdministerUsersController : LocalisingController
    {
        private const string FailedToDeleteMessage = "Error occurred during deletion of account with ID {0}.\nError message: {1}";
        
        public AdministerUsersController(IAccountProvider accountProvider, ILogger logger) : base(accountProvider, logger)
        {
            
        }

        //
        // GET: /Admin/
        [RequireSsl]
        [Authorize(Roles = "Administrator")]
        public virtual ActionResult Index()
        {
            return View();
        }

        [RequireSsl]
        [Authorize(Roles = "Administrator")]
        [AcceptVerbs(HttpVerbs.Post)]
        public virtual ActionResult GridData(string sidx, string sord, int page, int rows)
        {
            var pageIndex = Convert.ToInt32(page) - 1;
            var pageSize = rows;
            var totalRecords = AccountProvider.TotalAccounts(CurrentAccount);
            var totalPages = (int)Math.Ceiling(totalRecords / (float)pageSize);
            var accounts = AccountProvider.Accounts(CurrentAccount, pageIndex * pageSize, pageSize);

            var jsonData = new
            {
                total = totalPages,
                page,
                records = totalRecords,
                rows = (
                    from account in accounts.ToArray()
                    select new
                    {
                        id = account.AccountId,
                        cell = new [] { "", account.Username, AccountProvider.EmailForAccount(account), account.IsAdministrator.ToString() }
                    }
                ).ToArray()
            };

            var result = Json(jsonData);
            return result;
        }

        [RequireSsl]
        [Authorize(Roles = "Administrator")]
        public virtual ActionResult Edit(int id)
        {
            try
            {
                ViewData.Model = AccountProvider.GetAccount(CurrentAccount, id);
                return View();
            }
            catch (AuthorizationException)
            {
                return this.RedirectToUnauthorized();
            }
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [RequireSsl]
        [Authorize(Roles = "Administrator")]
        public virtual ActionResult Edit(int id, bool isAdministrator)
        {
            try
            {
                AccountProvider.AdminUpdateAccount(CurrentAccount, id, isAdministrator);
                return RedirectToAction(MVC.AdministerUsers.Index());
            }
            catch(ValidationException ve)
            {
                ve.AddToModelState(ViewData.ModelState);
                return View();
            }
            catch (AuthorizationException)
            {
                return this.RedirectToUnauthorized();
            }
        }

        [RequireSsl]
        [Authorize(Roles = "Administrator")]
        public virtual ActionResult Delete(int? id)
        {
            if (Request.IsAjaxRequest() && id != null)
            {
                // stop an administrator from being able to delete themselves through the grid view
                if (id.Value == CurrentAccount.AccountId)
                    return Json(false);
                try
                {
                    AccountProvider.Delete(CurrentAccount, id.Value);                    
                }
                catch (Exception ex)
                {
                    Logger.Warning(String.Format(FailedToDeleteMessage, id.Value, ex.Message));
                    return Json(false);
                }
                return Json(true);
            }
            return new EmptyResult();
        }
    }
}
